home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / sys / sysSysCall.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  31KB  |  760 lines

  1. /*
  2.  * sysSyscall.c --
  3.  *
  4.  *    Routines and structs for system calls.  Contains information
  5.  *    about each system call such as the number of arguments and how
  6.  *    to invoke the call for migrated processes.  All local
  7.  *    processes invoke system calls by copying in the arguments from
  8.  *    the user's address space and passing them to the kernel
  9.  *    routine uninterpreted.  When migrated processes invoke system
  10.  *    calls, when possible the arguments are passed to a generic
  11.  *    stub that packages the arguments and sends them to the home
  12.  *    node of the process through RPC.  This file contains
  13.  *    information about the sizes and types of each argument for
  14.  *    those procedures.  The generic stub is called with information
  15.  *    about which system call was invoked and what its arguments consist
  16.  *    of.  The information stored for each argument is described below.
  17.  *
  18.  *    Many system calls, however, are handled exclusively on the
  19.  *    current machine or are processed by special-purpose routines
  20.  *    on the current machine before being sent to the home machine.
  21.  *    In these cases no information about parameter types is kept,
  22.  *    and the procedure is invoked in the same manner as for local
  23.  *    processes.
  24.  *
  25.  *    NOTES ON ADDING SYSTEM CALLS:
  26.  *       Add an entry for the system call to the two arrays
  27.  *       declared below, sysCalls and paramsArray.  For sysCalls,
  28.  *       list the procedures to be invoked, whether to use the
  29.  *       generic stub (in which case special == FALSE), and the number
  30.  *       of words passed to the system call.  For paramsArray, if
  31.  *       special is FALSE, list the type and disposition of each
  32.  *       parameter.  If special is TRUE, just add a comment as a
  33.  *       placeholder within the array.  Finally, add an entry in
  34.  *       procRpc.c for the callback routine corresponding to the new
  35.  *       procedure (NIL if the call is not migrated).
  36.  *
  37.  * Copyright 1985, 1988 Regents of the University of California
  38.  * Permission to use, copy, modify, and distribute this
  39.  * software and its documentation for any purpose and without
  40.  * fee is hereby granted, provided that the above copyright
  41.  * notice appear in all copies.  The University of California
  42.  * makes no representations about the suitability of this
  43.  * software for any purpose.  It is provided "as is" without
  44.  * express or implied warranty.
  45.  */
  46.  
  47. #ifndef lint
  48. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/sys/sysSysCall.c,v 9.14 92/06/15 22:29:27 jhh Exp $ SPRITE (Berkeley)";
  49. #endif not lint
  50.  
  51. #include <sprite.h>
  52. #include <fs.h>
  53. #include <sys.h>
  54. #include <sysInt.h>
  55. #include <dbg.h>
  56. #include <proc.h>
  57. #include <sync.h>
  58. #include <sched.h>
  59. #include <vm.h>
  60. #include <user/vm.h>
  61. #include <rpc.h>
  62. #include <prof.h>
  63. #include <devVid.h>
  64. #include <net.h>
  65. #include <sysSysCall.h>
  66. #include <sysSysCallParam.h>
  67. #include <status.h>
  68. #include <stdio.h>
  69. #include <sysTestCall.h>
  70. #include <user/sys/param.h>
  71.  
  72. /*
  73.  * Forward declarations to procedures defined in this file:
  74.  */
  75.  
  76. static int ErrorProc _ARGS_((void));
  77. static ReturnStatus OutputCallTimes _ARGS_((int numToCopy,
  78.                         Address buffer));
  79. static ReturnStatus SysMigCall _ARGS_((Sys_ArgArray args));
  80.  
  81. #define TMP_EXTERN
  82. #ifdef TMP_EXTERN
  83. extern    int Proc_RemoteExec();
  84. #endif
  85.  
  86. #ifndef CLEAN
  87. Boolean sysTraceSysCalls = FALSE;
  88. #endif CLEAN
  89.  
  90. /*
  91.  * For each system call, keep track of:
  92.  *    - which procedure to invoke if the process is local;
  93.  *    - which to invoke if it is remote;
  94.  *    - whether the remoteFunc is "special" and is to be invoked
  95.  *      without interpreting the arguments, or whether the generic
  96.  *      stub will be called (passing it information such as the
  97.  *      number of arguments and the type of system call);
  98.  *    - a pointer to an array of parameter information, which includes
  99.  *      the types and dispositions of each argument.  For "special"
  100.  *      routines, this pointer is NIL.  Refer to sysSysCallParam.h for
  101.  *      documentation on the Sys_CallParam type.
  102.  */
  103.  
  104. typedef struct {
  105.     ReturnStatus (*localFunc)();  /* procedure to invoke for local processes */
  106.     ReturnStatus (*remoteFunc)(); /* procedure to invoke for migrated procs */
  107.     Boolean special;          /* whether the remoteFunc is called without
  108.                      passing it additional information */
  109.     int numWords;          /* The number of 4-byte quantities that must
  110.                      be passed to the system call. */
  111.     Sys_CallParam *paramsPtr;      /* pointer to parameter information for
  112.                      generic stub to use */
  113. } SysCallEntry;
  114.  
  115. /*
  116.  * Sys_ParamSizes is an array of sizes corresponding to
  117.  * each system call argument type.  Sys_ParamSizesDecl is used to
  118.  * assign the elements of the array at compile time.  Due to compiler
  119.  * restrictions, sys_ParamSizes needs to be a "pointer" while
  120.  * sys_ParamSizesDecl is an "array".  The argument types are documented
  121.  * in sysSysCallParam.h.
  122.  */
  123.  
  124. int sys_ParamSizesDecl[] = {
  125.     sizeof(int),            /* SYS_PARAM_INT        */
  126.     sizeof(char),            /* SYS_PARAM_CHAR        */
  127.     sizeof(Proc_PID),            /* SYS_PARAM_PROC_PID        */
  128.     sizeof(Proc_ResUsage),        /* SYS_PARAM_PROC_RES        */
  129.     sizeof(Sync_Lock),            /* SYS_PARAM_SYNC_LOCK        */
  130.     sizeof(Fs_Attributes),        /* SYS_PARAM_FS_ATT        */
  131.     FS_MAX_PATH_NAME_LENGTH,        /* SYS_PARAM_FS_NAME        */
  132.     sizeof(Time),            /* SYS_PARAM_TIMEPTR        */
  133.     sizeof(Time) / 2,            /* SYS_PARAM_TIME1        */
  134.     sizeof(Time) / 2,            /* SYS_PARAM_TIME2        */
  135.     sizeof(int),            /* SYS_PARAM_VM_CMD        */
  136.     0,                     /* SYS_PARAM_DUMMY         */
  137.     sizeof(int),            /* SYS_PARAM_RANGE1         */
  138.     sizeof(int),            /* SYS_PARAM_RANGE2        */
  139.     sizeof(Proc_ControlBlock),        /* SYS_PARAM_PCB        */
  140.     sizeof(Fs_Device),            /* SYS_PARAM_FS_DEVICE        */
  141.     sizeof(Proc_PCBArgString),        /* SYS_PARAM_PCBARG        */
  142.     MAXHOSTNAMELEN,            /* SYS_PARAM_HOSTNAME        */
  143.  
  144. };
  145.  
  146. int *sys_ParamSizes = sys_ParamSizesDecl;
  147.  
  148. static int ErrorProc()
  149. {
  150.     printf("Warning: Obsolete system call.\n");
  151.     return(GEN_FAILURE);
  152. }
  153.  
  154. /*
  155.  * sysCalls --
  156.  *
  157.  *    This table is used during a system call trap to branch to the
  158.  *    correct procedure for each system call.  There are two functions,
  159.  *    one if the process is local, the other if the process is an immigrant.
  160.  *    The number of integers (parameters) on the user's stack that have
  161.  *    to be copied to the kernel stack is also listed here.  The last field
  162.  *    of each record is filled in dynamically but initialized here to NIL.
  163.  *
  164.  *    N.B.: The format of this table is relied on to generate the file
  165.  *    Dummy.c, a file with just the declarations of the system calls
  166.  *    and no body.  See the CreateDummy script in src/lib/libc.
  167.  */
  168.  
  169. #define NILPARM ((Sys_CallParam *) NIL)
  170. #define CAST    (ReturnStatus (*) ())
  171.  
  172. static SysCallEntry sysCalls[] = {
  173. /*
  174.  *    localFunc          remoteFunc       special numWords  NILPARM
  175.  */
  176. /* DON'T DELETE THIS LINE - CreateDummy depends on it */
  177.     Proc_Fork,               Proc_Fork,       TRUE,    2,   NILPARM,
  178.     Proc_Exec,               Proc_Exec,       TRUE,    5,   NILPARM,
  179.     CAST Proc_Exit,       CAST Proc_Exit,       TRUE,    1,   NILPARM,
  180.     Sync_WaitTime,           Sync_WaitTime,       TRUE,    2,   NILPARM,
  181.     Test_PrintOut,           Test_PrintOut,      TRUE,       10,   NILPARM,
  182.     Test_GetLine,           Test_GetLine,          TRUE,    2,   NILPARM,
  183.     Test_GetChar,           Test_GetChar,          TRUE,    1,   NILPARM,
  184.     Fs_OpenStub,           Fs_OpenStub,         TRUE,    4,   NILPARM,
  185.     Fs_ReadStub,           Fs_ReadStub,         TRUE,     4,   NILPARM,
  186.     Fs_WriteStub,           Fs_WriteStub,         TRUE,     4,   NILPARM,
  187.     Fs_UserClose,           Fs_UserClose,         TRUE,     1,   NILPARM,
  188.     Fs_RemoveStub,           Fs_RemoveStub,         TRUE,    1,   NILPARM,
  189.     Fs_RemoveDirStub,           Fs_RemoveDirStub,   TRUE,    1,   NILPARM,
  190.     Fs_MakeDirStub,           Fs_MakeDirStub,     TRUE,    2,   NILPARM,
  191.     Fs_ChangeDirStub,           Fs_ChangeDirStub,   TRUE,    1,   NILPARM,
  192.     Proc_Wait,               Proc_Wait,          TRUE,    8,   NILPARM,
  193.     Proc_Detach,           Proc_DoRemoteCall,  FALSE,    1,   NILPARM,
  194.     Proc_GetIDs,           Proc_GetIDs,         TRUE,    4,   NILPARM,
  195.     Proc_SetIDs,           Proc_DoRemoteCall,  FALSE,    2,   NILPARM,
  196.     Proc_GetGroupIDs,           Proc_GetGroupIDs,   TRUE,    3,   NILPARM,
  197. /*
  198.  * Need not be forwarded home because groups only used during FS operations.
  199.  */
  200.     Proc_SetGroupIDs,           Proc_SetGroupIDs,   TRUE,    2,   NILPARM,
  201. /*
  202.  * Must be forwarded home because can ask about arbitrary process on home node.
  203.  */
  204.     Proc_GetFamilyID,           Proc_DoRemoteCall,  FALSE,    2,   NILPARM,
  205.     Proc_SetFamilyID,           Proc_DoRemoteCall,  FALSE,    2,   NILPARM,
  206.     Test_RpcStub,           Test_RpcStub,          TRUE,    4,   NILPARM,
  207.     Sys_StatsStub,           Sys_StatsStub,      TRUE,    4,   NILPARM,
  208.     Vm_CreateVA,           Vm_CreateVA,       TRUE,     2,   NILPARM,
  209.     Vm_DestroyVA,           Vm_DestroyVA,       TRUE,     2,   NILPARM,
  210.     Sig_UserSend,           Sig_UserSend,         TRUE,    3,   NILPARM,
  211.     Sig_Pause,               Sig_Pause,          TRUE,    1,   NILPARM,
  212.     Sig_SetHoldMask,           Sig_SetHoldMask,    TRUE,    2,   NILPARM,
  213.     Sig_SetAction,           Sig_SetAction,      TRUE,    3,   NILPARM,
  214.     Prof_Start,               Prof_Start,         TRUE,    0,   NILPARM,
  215.     Prof_End,               Prof_End,         TRUE,    0,   NILPARM,
  216.     Prof_DumpStub,           Prof_DumpStub,         TRUE,    1,   NILPARM,
  217.     Vm_Cmd,               Vm_Cmd,         TRUE,    2,   NILPARM,
  218.     Sys_GetTimeOfDay,           Proc_DoRemoteCall,  FALSE,    3,   NILPARM,
  219.     Sys_SetTimeOfDay,           Proc_DoRemoteCall,  FALSE,    3,   NILPARM,
  220.     Sys_DoNothing,           Sys_DoNothing,      TRUE,    0,   NILPARM,
  221.     Proc_GetPCBInfo,           Proc_GetPCBInfo,    TRUE,    7,   NILPARM,
  222.     Vm_GetSegInfo,           Vm_GetSegInfo,      TRUE,    4,   NILPARM,
  223.     Proc_GetResUsage,           Proc_GetResUsage,   TRUE,    2,   NILPARM,
  224.     Proc_GetPriority,           Proc_GetPriority,   TRUE,    2,   NILPARM,
  225.     Proc_SetPriority,          Proc_SetPriority,   TRUE,    3,   NILPARM,
  226.     Proc_Debug,               Proc_Debug,          TRUE,    5,   NILPARM,
  227.     Proc_Profile,           Proc_Profile,       TRUE,    6,   NILPARM,
  228.     ErrorProc,               ErrorProc,          TRUE,    2,   NILPARM,
  229.     ErrorProc,                  ErrorProc,        TRUE,    2,   NILPARM,
  230.     Fs_GetNewIDStub,           Fs_GetNewIDStub,    TRUE,    2,   NILPARM,
  231.     Fs_GetAttributesStub,      Fs_GetAttributesStub, TRUE,    3,   NILPARM,
  232.     Fs_GetAttributesIDStub,    Fs_GetAttributesIDStub, TRUE,    2,   NILPARM,
  233.     Fs_SetAttributesStub,      Fs_SetAttributesStub, TRUE,    3,   NILPARM,
  234.     Fs_SetAttributesIDStub,    Fs_SetAttributesIDStub, TRUE,    2,   NILPARM,
  235.     Fs_SetDefPermStub,           Fs_SetDefPermStub,  TRUE,    2,   NILPARM,
  236.     Fs_IOControlStub,           Fs_IOControlStub,   TRUE,    6,   NILPARM,
  237.     Dev_VidEnable,           Proc_DoRemoteCall,  FALSE,    1,   NILPARM,
  238.     /*
  239.      * The following ErrorProc listings correspond to obsolete
  240.      * environment-related procedures.
  241.      */
  242.     ErrorProc,               ErrorProc,  TRUE,    2,   NILPARM,
  243.     ErrorProc,             ErrorProc,  TRUE,    2,   NILPARM,
  244.     ErrorProc,            ErrorProc,  TRUE,    2,   NILPARM,
  245.     ErrorProc,          ErrorProc,   TRUE,    4,   NILPARM,
  246.     ErrorProc,           ErrorProc,   TRUE,    2,   NILPARM,
  247.     ErrorProc,              ErrorProc,  TRUE,    0,   NILPARM,
  248.  
  249.     Sync_SlowLockStub,           Sync_SlowLockStub,  TRUE,    1,   NILPARM,
  250.     Sync_SlowWaitStub,           Sync_SlowWaitStub,  TRUE,    3,   NILPARM,
  251.     Sync_SlowBroadcastStub,    Sync_SlowBroadcastStub,  TRUE,    2,   NILPARM,
  252.     Vm_PageSize,        Vm_PageSize,         TRUE,    1,   NILPARM,
  253.     Fs_HardLinkStub,        Fs_HardLinkStub,   TRUE,    2,   NILPARM,
  254.     Fs_RenameStub,        Fs_RenameStub,        TRUE,    2,   NILPARM,
  255.     Fs_SymLinkStub,        Fs_SymLinkStub,    TRUE,    3,   NILPARM,
  256.     Fs_ReadLinkStub,        Fs_ReadLinkStub,   TRUE,    4,   NILPARM,
  257.     Fs_CreatePipeStub,        Fs_CreatePipeStub, TRUE,    2,   NILPARM,
  258.     VmMach_MapKernelIntoUser,    Proc_RemoteDummy, FALSE,    4,   NILPARM,
  259.     Fs_AttachDiskStub,        Proc_DoRemoteCall, FALSE,    3,   NILPARM,
  260.     Fs_SelectStub,        Fs_SelectStub,        TRUE,    6,   NILPARM,
  261.     CAST Sys_Shutdown,        Sys_Shutdown,        TRUE,    2,   NILPARM,
  262.     Proc_Migrate,        Proc_DoRemoteCall, FALSE,    2,   NILPARM,
  263.     Fs_MakeDeviceStub,        Proc_DoRemoteCall, FALSE,    3,   NILPARM,
  264.     Fs_CommandStub,        Fs_CommandStub,    TRUE,    3,   NILPARM,
  265.     ErrorProc,               ErrorProc,        TRUE,    2,   NILPARM,
  266.     Sys_GetMachineInfo,           Sys_GetMachineInfo,  TRUE,    3,   NILPARM,
  267.     Net_InstallRouteStub,     Net_InstallRouteStub, TRUE,     6,   NILPARM,
  268.     Fs_ReadVectorStub,         Fs_ReadVectorStub, TRUE,     4,   NILPARM,
  269.     Fs_WriteVectorStub,     Fs_WriteVectorStub, TRUE,     4,   NILPARM,
  270.     Fs_CheckAccess,         Fs_CheckAccess,     TRUE,    3,   NILPARM,
  271.     Proc_GetIntervalTimer,    Proc_GetIntervalTimer,     TRUE,    2,   NILPARM,
  272.     Proc_SetIntervalTimer,    Proc_SetIntervalTimer,     TRUE,    3,   NILPARM,
  273.     Fs_FileWriteBackStub,    Fs_FileWriteBackStub, TRUE,    4,   NILPARM,
  274.     Proc_ExecEnv,        Proc_ExecEnv,       TRUE,    4,   NILPARM,
  275.     Fs_SetAttrStub,        Fs_SetAttrStub,       TRUE,    4,   NILPARM,
  276.     Fs_SetAttrIDStub,        Fs_SetAttrIDStub,   TRUE,    3,   NILPARM,
  277.     Proc_GetHostIDs,        Proc_GetHostIDs,   TRUE,    2,   NILPARM,
  278.     Sched_IdleProcessor,    Sched_IdleProcessor,  TRUE,    1,   NILPARM,
  279.     Sched_StartProcessor,    Sched_StartProcessor,   TRUE,    1,   NILPARM,
  280. #if 0
  281.     Mach_GetNumProcessors,    Mach_GetNumProcessors,   TRUE,    1,   NILPARM,
  282. #else
  283.     0,                          0,                      TRUE,   1,   NILPARM,
  284. #endif
  285.     Prof_Profil,                Prof_Profil,            TRUE,   4,   NILPARM,
  286.     Proc_RemoteExec,        Proc_RemoteExec,   TRUE,    4,   NILPARM,
  287.     Sys_GetMachineInfoNew,    Sys_GetMachineInfoNew,   TRUE,    2,   NILPARM,
  288.     Vm_Mmap,            Vm_Mmap,        TRUE,    7,   NILPARM,
  289.     Vm_Munmap,            Vm_Munmap,        TRUE,    3,   NILPARM,
  290.     Vm_Msync,            Vm_Msync,        TRUE,    2,   NILPARM,
  291.     Vm_Mlock,            Vm_Mlock,        TRUE,    2,   NILPARM,
  292.     Vm_Munlock,            Vm_Munlock,        TRUE,    2,   NILPARM,
  293.     Vm_Mincore,            Vm_Mincore,        TRUE,    3,   NILPARM,
  294.     Sync_SemctlStub,        Sync_SemctlStub,    TRUE,    5,   NILPARM,
  295.     Sync_SemgetStub,        Sync_SemgetStub,    TRUE,    4,   NILPARM,
  296.     Sync_SemopStub,        Sync_SemopStub,        TRUE,    4,   NILPARM,
  297.     Vm_Mprotect,        Vm_Mprotect,        TRUE,   3,   NILPARM,
  298.     Proc_Vfork,                    Proc_Vfork,            TRUE,    0,   NILPARM,
  299.     Net_GetRoutes,        Net_GetRoutes,        TRUE,    5,   NILPARM,
  300.     Net_DeleteRouteStub,    Net_DeleteRouteStub,    TRUE,    1,   NILPARM,
  301.     /*
  302.      * The following are placeholders for Zebra system calls which aren't 
  303.      * in the standard kernel. 
  304.      */
  305.     ErrorProc,           ErrorProc,           TRUE,    3,   NILPARM,
  306.     ErrorProc,           ErrorProc,           TRUE,    3,   NILPARM,
  307.     Sys_GetHostName,        Proc_DoRemoteCall,     FALSE,    1,   NILPARM,
  308.     Sys_SetHostName,        Proc_DoRemoteCall,     FALSE,    1,   NILPARM,
  309. };
  310.  
  311.  
  312. /*
  313.  * paramsArray is a static array of parameter information.  The array is
  314.  * one gigantic array so that it may be initialized at compile time, but
  315.  * conceptually it is distinct arrays, one per system call.  SysInitSysCall,
  316.  * called at system initialization time, maps points within this array
  317.  * to paramsPtr fields within the sysCalls array.  ParamsPtr is initialized
  318.  * to NIL at compile time, but for procedures that are not flagged as
  319.  * "special", paramsPtr is reset to point into paramsArray at the point of
  320.  * the first Sys_CallParam structure corresponding to that procedure.
  321.  *
  322.  * For system calls that are "special", there is no entry in paramsArray.
  323.  * However, a comment with the system call number and " special" is useful
  324.  * to keep track of the correspondence between parameter information and
  325.  * the rest of the sysCall struct.  Note that "special" is equivalent to
  326.  * "local": "special" usually means a special-purpose routine is called,
  327.  * while "local" means the same routine is used for both local and migrated
  328.  * processes.
  329.  *
  330.  * The format of paramsArray is as follows.  For each non-special
  331.  * SysCallEntry, there should be -numWords- Sys_CallParam structures.
  332.  * A number of defined constants are given to simplify the information
  333.  * given for each one.  Essentially, the crucial things to consider are
  334.  * whether a given parameter is passed IN to a procedure, OUT of it, or
  335.  * both.  At the same time, is the parameter passed into the system call
  336.  * in its entirety, such as an integer; or is the parameter a pointer to
  337.  * something that needs to be copied into or out of the kernel address
  338.  * space, or made accessible?  Finally, if the parameter is a pointer, is
  339.  * it a pointer to an object of fixed size or does it point to an array
  340.  * of objects?  The generic stub will handle arrays if the size of the
  341.  * array is an IN parameter that is passed in just before the pointer to
  342.  * the array, in the argument list.  It will also handle arrays with
  343.  * a range of numbers that indicates the size of the array; for example,
  344.  * if the preceding arguments were 2 and 5, the size of the array would
  345.  * be (5 - 2 + 1) * sizeof(...).
  346.  *
  347.  * Note that multi-word parameters must be treated in this array as
  348.  * *separate* arguments.  For example, Time structures are given as
  349.  * TIME1 and TIME2.  This is because the procedures & structures in this
  350.  * file do not know the actual number of arguments, but rather the number
  351.  * of words that a system call is passed.
  352.  */
  353.  
  354. #define PARM         0
  355. #define PARM_I         SYS_PARAM_IN
  356. #define PARM_O         SYS_PARAM_OUT
  357. #define PARM_IO        (SYS_PARAM_IN | SYS_PARAM_OUT)
  358. #define PARM_IA     (SYS_PARAM_IN | SYS_PARAM_ACC)
  359. #define PARM_OA     (SYS_PARAM_OUT | SYS_PARAM_ACC)
  360. #define PARM_IOA    (PARM_IO | SYS_PARAM_ACC)
  361. #define PARM_IC     (SYS_PARAM_IN | SYS_PARAM_COPY)
  362. #define PARM_OC        (SYS_PARAM_OUT | SYS_PARAM_COPY)
  363. #define PARM_IOC    (PARM_IO | SYS_PARAM_COPY)
  364. #define PARM_ICR     (SYS_PARAM_IN | SYS_PARAM_COPY | SYS_PARAM_ARRAY)
  365. #define PARM_OCR    (SYS_PARAM_OUT | SYS_PARAM_COPY | SYS_PARAM_ARRAY)
  366.  
  367. static Sys_CallParam paramsArray[] = {
  368.     /* special */                /* SYS_PROC_FORK    0 */
  369.     /* special */                     /* SYS_PROC_EXEC    1 */
  370.     /* special */                 /* SYS_PROC_EXIT    2 */
  371.     /* local */                          /* SYS_SYNC_WAITTIME    3 */
  372.     /* local */                    /* SYS_TEST_PRINTOUT    4 */
  373.     /* local */                    /* SYS_TEST_GETLINE    5 */
  374.     /* local */                    /* SYS_TEST_GETCHAR    6 */
  375.     /* local */                    /* SYS_FS_OPEN        7 */
  376.     /* local */                    /* SYS_FS_READ        8 */
  377.     /* local */                    /* SYS_FS_WRITE        9 */
  378.     /* local */                    /* SYS_FS_CLOSE        10 */
  379.     /* local */                    /* SYS_FS_REMOVE    11 */
  380.     /* local */                    /* SYS_FS_REMOVE_DIR    12 */
  381.     /* local */                    /* SYS_FS_MAKE_DIR    13 */
  382.     /* local */                    /* SYS_FS_CHANGE_DIR    14 */
  383.     /* special */                     /* SYS_PROC_WAIT    15 */
  384.     SYS_PARAM_INT,          PARM_I,        /* SYS_PROC_DETACH    16 */
  385.     /* local */                         /* SYS_PROC_GETIDS    17 */
  386.     SYS_PARAM_INT,          PARM_I,        /* SYS_PROC_SETIDS    18 */
  387.     SYS_PARAM_INT,          PARM_I,
  388.     /* local */                         /* SYS_PROC_GETGROUPIDS 19 */
  389.     /* local */                         /* SYS_PROC_SETGROUPIDS 20 */
  390.     SYS_PARAM_PROC_PID,          PARM_I,        /* SYS_PROC_GETFAMILYID 21 */
  391.     SYS_PARAM_PROC_PID,          PARM_OC,
  392.     SYS_PARAM_PROC_PID,          PARM_I,        /* SYS_PROC_SETFAMILYID 22 */
  393.     SYS_PARAM_INT,          PARM_I,
  394.     /* test */                    /* SYS_TEST_RPC        23 */
  395.     /* test */                    /* SYS_SYS_STATS    24 */
  396.     /* local */                    /* SYS_VM_CREATEVA    25 */
  397.     /* local */                    /* SYS_VM_DESTROYVA    26 */
  398.     /* local */                    /* SYS_SIG_SEND        27 */
  399.     /* local */                 /* SYS_SIG_PAUSE    28 */
  400.     /* local */                 /* SYS_SIG_SETHOLDMASK    29 */
  401.     /* local */                         /* SYS_SIG_SETACTION    30 */
  402.  
  403.     /* local */                         /* SYS_PROF_START    31 */
  404.     /* local */                         /* SYS_PROF_END        32 */
  405.     /* local */                         /* SYS_PROF_DUMP    33 */
  406.     /* local */                    /* SYS_VM_CMD        34 */
  407.     SYS_PARAM_TIMEPTR,          PARM_OC,        /* SYS_SYS_GETTIMEOFDAY 35 */
  408.     SYS_PARAM_INT,          PARM_OC,
  409.     SYS_PARAM_INT,          PARM_OC,
  410.     SYS_PARAM_TIMEPTR,          PARM_IC,        /* SYS_SYS_SETTIMEOFDAY 36 */
  411.     SYS_PARAM_INT,          PARM_I,
  412.     SYS_PARAM_INT,          PARM_I,
  413.     /* local */                         /* SYS_SYS_DONOTHING    37 */
  414.     /* local */                         /* SYS_PROC_GETPCBINFO    38 */
  415.     /* local */                    /* SYS_VM_GETSEGINFO    39 */
  416.     /* local */                    /* SYS_PROC_GETRESUSAGE 40 */
  417.     /* local */                    /* SYS_PROC_GETPRIORITY 41 */
  418.     /* local */                    /* SYS_PROC_SETPRIORITY 42 */
  419.     /* special (don't migrate?) */             /* SYS_PROC_DEBUG    43 */
  420.     /* local case not implemented */        /* SYS_PROC_PROFILE    44 */
  421.     /* local */                    /* SYS_FS_TRUNC        45 */
  422.     /* local */                    /* SYS_FS_TRUNC_ID    46 */
  423.     /* local */                 /* SYS_FS_GET_NEW_ID    47 */
  424.     /* local */                    /* SYS_FS_GET_ATTRIBUTES 48 */
  425.     /* local */                 /* SYS_FS_GET_ATTR_ID    49 */
  426.     /* local */                    /* SYS_FS_SET_ATTRIBUTES 50 */
  427.     /* local */                 /* SYS_FS_SET_ATTR_ID    51 */
  428.     /* local */                    /* SYS_FS_SET_DEF_PERM    52 */
  429.     /* local */                         /* SYS_FS_IO_CONTROL    53 */
  430.     SYS_PARAM_INT,          PARM_I,        /* SYS_SYS_ENABLEDISPLAY 54 */
  431.     /* obsolete */                /* SYS_PROC_SET_ENVIRON 55 */
  432.     /* obsolete */                /* SYS_PROC_UNSET_ENVIRON 56 */
  433.     /* obsolete */                /* ..._GET_ENVIRON_VAR    57 */
  434.     /* obsolete */                /* ..._GET_ENVIRON_RANGE 58 */
  435.     /* obsolete */                /* ..._INSTALL_ENVIRON    59 */
  436.     /* obsolete */                /* SYS_PROC_COPY_ENVIRON 60 */
  437.     /* local */                    /* SYS_SYNC_SLOWLOCK    61 */
  438.     /* local */                    /* SYS_SYNC_SLOWWAIT    62 */
  439.     /* local */                    /* SYS_SYNC_SLOWBROADCAST 63 */
  440.     /* local */                    /* SYS_VM_PAGESIZE    64 */
  441.     /* local */                    /* SYS_FS_HARDLINK    65 */
  442.     /* local */                    /* SYS_FS_RENAME    66 */
  443.     /* local */                    /* SYS_FS_SYMLINK    67 */
  444.     /* local */                    /* SYS_FS_READLINK    68 */
  445.     /* local */                    /* SYS_FS_CREATEPIPE    69 */
  446.     SYS_PARAM_INT,          PARM_I,        /* ..VM_MAPKERNELINTOUSER 70 */
  447.     SYS_PARAM_INT,          PARM_I,
  448.     SYS_PARAM_INT,          PARM_I,
  449.     SYS_PARAM_INT,          PARM_OC,
  450.     SYS_PARAM_FS_NAME,          PARM_IA,        /* SYS_FS_ATTACH_DISK    71 */
  451.     SYS_PARAM_FS_NAME,          PARM_IA,
  452.     SYS_PARAM_INT,          PARM_I,
  453.     /* local */                         /* SYS_FS_SELECT    72 */
  454.     /* local */                    /* SYS_SYS_SHUTDOWN    73 */
  455.     SYS_PARAM_PROC_PID,          PARM_I,        /* SYS_PROC_MIGRATE    74 */
  456.     SYS_PARAM_INT,          PARM_I,
  457.     SYS_PARAM_FS_NAME,           PARM_IA,        /* SYS_FS_MAKE_DEVICE    75 */
  458.     SYS_PARAM_FS_DEVICE,      PARM_IC,
  459.     SYS_PARAM_INT,          PARM_I,
  460.     /* local */                    /* SYS_FS_COMMAND    76 */
  461.     /* local */                    /* -obsolete-        77 */
  462.     /* local */                    /* SYS_GETMACHINEINFO    78 */
  463.     /* special */                /* SYS_NET_INSTALL_ROUTE 79 */
  464.     /* local */                    /* SYS_FS_READVECTOR    80 */
  465.     /* local */                    /* SYS_FS_WRITEVECTOR    81 */
  466.     /* local */                    /* SYS_FS_CHECKACCESS    82 */
  467.     /* local */                /* SYS_PROC_GETINTERVALTIMER    83 */
  468.     /* local */                /* SYS_PROC_SETINTERVALTIMER    84 */
  469.     /* local */                /* SYS_FS_WRITEBACKID        85 */
  470.     /* special */                     /* SYS_PROC_EXEC_ENV    86 */
  471.     /* local */                /* SYS_FS_SET_ATTR_NEW        87 */
  472.     /* local */             /* SYS_FS_SET_ATTR_ID_NEW    88 */
  473.     /* local */             /* SYS_PROC_GETHOSTIDS        89 */
  474.     /* local */             /* SYS_SCHED_IDLE_PROCESSOR    90 */
  475.     /* local */             /* SYS_SCHED_START_PROCESSOR    91 */
  476.     /* local */             /* SYS_MACH_NUM_PROCESSORS    92 */
  477.     /* local */                         /* SYS_PROF_PROFIL              93 */
  478.     /* local */                         /* SYS_PROC_REMOTE_EXEC         94 */
  479.     /* local */                         /* SYS_SYS_GETMACHINEINFO_NEW   95 */
  480.     /* local */                         /* SYS_VM_MMAP            96 */
  481.     /* local */                         /* SYS_VM_MUNMAP        97 */
  482.     /* local */                         /* SYS_VM_MSYNC            98 */
  483.     /* local */                         /* SYS_VM_MLOCK            99 */
  484.     /* local */                         /* SYS_VM_MUNLOCK        100 */
  485.     /* local */                         /* SYS_VM_MINCORE        101 */
  486.     /* local */                         /* SYS_SYNC_SEMCTL        102 */
  487.     /* local */                         /* SYS_SYNC_SEMGET        103 */
  488.     /* local */                         /* SYS_SYNC_SEMOP        104 */
  489.     /* local */                         /* VM_MPROTECT            105 */
  490.     /* special */            /* SYS_PROC_VFORK            106 */
  491.     /* local */                /* SYS_NET_GET_ROUTES        107 */
  492.     /* local */                /* SYS_NET_DELETE_ROUTE        108 */
  493.     /* local */                /* SYS_ZSS_CMD            109 */
  494.     /* local */                /* SYS_ZEBRA_CMD        110 */
  495.     SYS_PARAM_HOSTNAME,        PARM_OC,    /* SYS_SYS_GET_HOSTNAME    111 */
  496.     SYS_PARAM_HOSTNAME,        PARM_IA,    /* SYS_SYS_SET_HOSTNAME    112 */
  497.  
  498.     /*
  499.      * Insert new system call information above this line.
  500.      */
  501.     NIL,              NIL        /* array compatibility check */
  502. };
  503.  
  504. /*
  505.  * Define an array to count the number of system calls performed for local
  506.  * and foreign processes, as well as subscripts and a macro to reset it.
  507.  */
  508.  
  509. #define LOCAL_CALL 0
  510. #define FOREIGN_CALL 1
  511. int sys_NumCalls[SYS_NUM_SYSCALLS];
  512. #define RESET_NUMCALLS() bzero((Address) sys_NumCalls, \
  513.                 SYS_NUM_SYSCALLS * sizeof(int));
  514.  
  515. /* 
  516.  * Define an array of ticks, to keep track of the total time spent in each 
  517.  * system call.  sys_CallProfiling indicates whether to maintain the array 
  518.  * or not.
  519.  */
  520.  
  521. Boolean sys_CallProfiling = FALSE;
  522. Timer_Ticks sys_CallTimes[SYS_NUM_SYSCALLS];
  523.  
  524.  
  525. /*
  526.  *----------------------------------------------------------------------
  527.  *
  528.  * SysInitSysCall --
  529.  *
  530.  *    Initialize the data structures for performing a system call.
  531.  *    Make sure the last entry in the array of parameters is (NIL, NIL)
  532.  *     (serving as a cross check on the total number of parameters to
  533.  *    be initialized).  Initialize the count of the number of system
  534.  *    calls performed.
  535.  *
  536.  * Results:
  537.  *    None.
  538.  *
  539.  * Side effects:
  540.  *    The mapping between system calls and their argument types is
  541.  *    established.
  542.  *
  543.  *----------------------------------------------------------------------
  544.  */
  545.  
  546. void
  547. SysInitSysCall()
  548. {
  549.     int sysCallNum;
  550.     SysCallEntry *entryPtr;
  551.     Sys_CallParam *paramPtr;
  552.  
  553.     paramPtr = paramsArray;
  554.     entryPtr = sysCalls;
  555.     for (sysCallNum = 0; sysCallNum < SYS_NUM_SYSCALLS; sysCallNum++) {
  556.     if (!entryPtr->special) {
  557.         entryPtr->paramsPtr = paramPtr;
  558.         paramPtr += entryPtr->numWords;
  559.     /*
  560.      * Won't lint due to cast of function pointer.
  561.      */
  562. #ifndef lint
  563.         Mach_InitSyscall(sysCallNum, entryPtr->numWords,
  564.             entryPtr->localFunc, SysMigCall);
  565. #endif /* lint */
  566.     } else {
  567.     /*
  568.      * Won't lint due to cast of function pointer.
  569.      */
  570. #ifndef lint
  571.         Mach_InitSyscall(sysCallNum, entryPtr->numWords,
  572.             entryPtr->localFunc, entryPtr->remoteFunc);
  573. #endif /* lint */
  574.     }
  575.     entryPtr++;
  576.     }
  577.     if (paramPtr->type != NIL || paramPtr->disposition != NIL) {
  578.     panic("SysInitSysCall: error initializing parameter array.\n");
  579.     }
  580.     RESET_NUMCALLS();
  581. }
  582.  
  583. /*
  584.  *----------------------------------------------------------------------
  585.  *
  586.  * SysMigCall --
  587.  *
  588.  *    This procedure is invoked whenever a migrated process invokes
  589.  *    a kernel call that doesn't have "special" set.  It arranges
  590.  *    for the kernel call to be sent home in a standard fashion.
  591.  *
  592.  * Results:
  593.  *    Returns the result of the kernel call, whatever that is.
  594.  *
  595.  * Side effects:
  596.  *    Depends on the kernel call.
  597.  *
  598.  *----------------------------------------------------------------------
  599.  */
  600.  
  601. static ReturnStatus
  602. SysMigCall(args)
  603.     Sys_ArgArray args;            /* The arguments to the system call. */
  604. {
  605.     int sysCall;
  606.     register SysCallEntry *entryPtr;
  607.  
  608.     sysCall = Mach_GetLastSyscall();
  609.     entryPtr = &sysCalls[sysCall];
  610.     return (*entryPtr->remoteFunc)(sysCall, entryPtr->numWords,
  611.         (ClientData *) &args, entryPtr->paramsPtr);
  612. }
  613.  
  614. /*
  615.  *----------------------------------------------------------------------
  616.  *
  617.  * Sys_OutputNumCalls --
  618.  *
  619.  *    Copy the number of invocations of system calls into user space.
  620.  *    Takes an argument, the number of calls to copy, which indicates the
  621.  *    size of the user's buffer.  This is protection against any
  622.  *    inconsistency between the kernel and user program's ideas of how
  623.  *    many system calls there are.  An argument of 0 calls indicates that
  624.  *    the statistics should be reset to 0.
  625.  *
  626.  * Results:
  627.  *    The return status from Vm_CopyOut is returned.
  628.  *
  629.  * Side effects:
  630.  *    Data is copied into user space.
  631.  *
  632.  *----------------------------------------------------------------------
  633.  */
  634.  
  635. ReturnStatus
  636. Sys_OutputNumCalls(requestedCount, buffer, doTimes)
  637.     int requestedCount;    /* number of system calls statistics to copy */
  638.     Address buffer;        /* start address of user's buffer */
  639.     Boolean doTimes;        /* copy per-call times as well */
  640. {
  641.     ReturnStatus status = SUCCESS;
  642.     int numToCopy;        /* number of calls actually copied out */
  643.  
  644.     if (requestedCount == 0) {
  645.     RESET_NUMCALLS();
  646.     bzero(sys_CallTimes, SYS_NUM_SYSCALLS * sizeof(Timer_Ticks));
  647.     } else {
  648.     /* 
  649.      * If the user wants the per-call times as well, put them after the 
  650.      * per-call counts.  If there are fewer calls than the user 
  651.      * requested, there will be a gap.  (Otherwise, how would the user 
  652.      * know where to find the times?)
  653.      */
  654.     numToCopy = (requestedCount > SYS_NUM_SYSCALLS
  655.              ? SYS_NUM_SYSCALLS
  656.              : requestedCount);
  657.     status = Vm_CopyOut(numToCopy * sizeof(int), (Address) sys_NumCalls,
  658.                 buffer);
  659.     if (doTimes && status == SUCCESS) {
  660.         status = OutputCallTimes(numToCopy,
  661.                      buffer + requestedCount * sizeof(int));
  662.     }
  663.     }
  664.     return(status);
  665. }
  666.  
  667.  
  668. /*
  669.  *----------------------------------------------------------------------
  670.  *
  671.  * OutputCallTimes --
  672.  *
  673.  *    Copy the per-call times to a user buffer.
  674.  *
  675.  * Results:
  676.  *    Returns the usual Sprite status code.
  677.  *
  678.  * Side effects:
  679.  *    The current cumulative times for the system calls are converted 
  680.  *    from Ticks to Time's and then copied out.
  681.  *
  682.  *----------------------------------------------------------------------
  683.  */
  684.  
  685. static ReturnStatus
  686. OutputCallTimes(numToCopy, buffer)
  687.     int numToCopy;        /* number of calls to copy; already 
  688.                  * truncated if necessary*/
  689.     Address buffer;        /* where to put the times */
  690. {
  691.     Time times[SYS_NUM_SYSCALLS];
  692.     int index;
  693.  
  694.     for (index = 0; index < SYS_NUM_SYSCALLS; ++index) {
  695.     Timer_TicksToTime(sys_CallTimes[index], ×[index]);
  696.     }
  697.  
  698.     return Vm_CopyOut(numToCopy * sizeof(Time), (Address)times,
  699.               buffer);
  700. }
  701.  
  702.  
  703. /*
  704.  *----------------------------------------------------------------------
  705.  *
  706.  * Sys_RecordCallStart --
  707.  *
  708.  *    Record the current time in the PCB.  Called at the start of a 
  709.  *    system call.
  710.  *
  711.  * Results:
  712.  *    None.
  713.  *
  714.  * Side effects:
  715.  *    None.
  716.  *
  717.  *----------------------------------------------------------------------
  718.  */
  719.  
  720. void
  721. Sys_RecordCallStart()
  722. {
  723.     Proc_ControlBlock *procPtr = Proc_GetCurrentProc();
  724.  
  725.     Timer_GetCurrentTicks(&procPtr->syscallStartTime);
  726. }
  727.  
  728.  
  729. /*
  730.  *----------------------------------------------------------------------
  731.  *
  732.  * Sys_RecordCallFinish --
  733.  *
  734.  *    Update the time spent for a particular system call.  Called after 
  735.  *    the call has been handled.
  736.  *
  737.  * Results:
  738.  *    None.
  739.  *
  740.  * Side effects:
  741.  *    Updates the appropriate tick count in sys_CallTimes.
  742.  *
  743.  *----------------------------------------------------------------------
  744.  */
  745.  
  746. void
  747. Sys_RecordCallFinish(callNum)
  748.     int callNum;        /* system call number */
  749. {
  750.     Timer_Ticks totalTime;
  751.     Timer_Ticks now;
  752.     Proc_ControlBlock *procPtr;
  753.  
  754.     procPtr = Proc_GetCurrentProc();
  755.     Timer_GetCurrentTicks(&now);
  756.     Timer_SubtractTicks(now, procPtr->syscallStartTime, &totalTime);
  757.     Timer_AddTicks(sys_CallTimes[callNum], totalTime,
  758.            &sys_CallTimes[callNum]);
  759. }
  760.